﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Irony.Ast;
using Irony.Parsing;

namespace AppServidor
{
    class sintacticoBtw:Grammar
    {
        public sintacticoBtw() { 
        
            StringLiteral cad = TerminalFactory.CreateCSharpString("cad");
            IdentifierTerminal id = TerminalFactory.CreateCSharpIdentifier("id");
            NumberLiteral num = TerminalFactory.CreateCSharpNumber("num");

            CommentTerminal escape = new CommentTerminal("escape", "\n", "\r");
            base.NonGrammarTerminals.Add(escape);
            
             NonTerminal LAM = new NonTerminal("LAM"),
           LSM = new NonTerminal("LSM"),
           CCM = new NonTerminal("CCM"),
           LCM = new NonTerminal("LCM"),
           Tip = new NonTerminal("Tip"),
           LP = new NonTerminal("LP"),
            LN = new NonTerminal("LN"),
           LPN = new NonTerminal("LPN"),
           LC = new NonTerminal("LC"),
           LNO = new NonTerminal("LNO"),
           LD = new NonTerminal("LD"),
           YN = new NonTerminal("YN"),
           S = new NonTerminal("S"),
           LSD = new NonTerminal("LSD"),
           NM = new NonTerminal("NM"),
           Idn = new NonTerminal("Idn");
           
            LAM.Rule= LAM+ LSM+Eos
                    | LSM+Eos;

CCM.Rule= ToTerm("<")+ToTerm("tipo")+ToTerm(">")+id+ToTerm("<")+ToTerm("/")+ToTerm("tipo")+ToTerm(">")
        | ToTerm("<") + ToTerm("tipo") + ToTerm(">") + Tip + ToTerm("<") + ToTerm("/") + ToTerm("tipo") + ToTerm(">")+Eos + ToTerm("<")+ToTerm("nombre")+ToTerm(">") + cad + ToTerm("<")+ToTerm("/")+ToTerm("nombre")+ToTerm(">")
        | ToTerm("<") + ToTerm("tipo") + ToTerm(">") + ToTerm("pistanueva") + ToTerm("<") + ToTerm("/") + ToTerm("tipo") + ToTerm(">") +Eos+ LD;

Tip.Rule= ToTerm("Lista")
		|ToTerm("Pista");

LSM.Rule = ToTerm("<") + ToTerm("listas") + ToTerm(">") +Eos+Indent+ LN +Eos+Dedent+ ToTerm("<") + ToTerm("/") + ToTerm("listas") + ToTerm(">")
        | ToTerm("<") + ToTerm("lista") + ToTerm("nombre") + ToTerm("=") + cad + ToTerm("aleatoria") + ToTerm("=") + YN + ToTerm(">") +Eos+Indent+ LPN +Eos+Dedent+ ToTerm("<") + ToTerm("/") + ToTerm("lista") + ToTerm(">")
        | ToTerm("<") + ToTerm("pistas") + ToTerm(">") +Eos+Indent+ LPN +Eos+Dedent+ ToTerm("<") + ToTerm("/") + ToTerm("pistas") + ToTerm(">")
        | ToTerm("<") + ToTerm("pista") + ToTerm("nombre") + ToTerm("=") + cad + ToTerm(">") +Eos+Indent+ LC +Eos+Dedent+ ToTerm("<") + ToTerm("/") + ToTerm("pista") + ToTerm(">")
        | ToTerm("<") + ToTerm("solicitud") + ToTerm(">") + Eos + Indent + CCM +Eos+Dedent + ToTerm("<") + ToTerm("/") + ToTerm("solicitud") + ToTerm(">");

YN.Rule= "\""+ToTerm("SI")+"\""
	|"\""+ToTerm("NO")+"\"";

LN.Rule=  LN + Eos+ToTerm("<") + ToTerm("lista") + ToTerm("nombre") + ToTerm("=") + cad + ToTerm("pistas") + ToTerm("=") + num + ToTerm(">")
        | ToTerm("<") + ToTerm("lista") + ToTerm("nombre") + ToTerm("=") + cad + ToTerm("pistas") + ToTerm("=") + num + ToTerm(">");

LPN.Rule= LPN +Eos+ ToTerm("<") + ToTerm("pista") + ToTerm("nombre") + ToTerm("=") + cad + ToTerm("duracion") + ToTerm("=") + num + ToTerm(">")
        | ToTerm("<") + ToTerm("pista") + ToTerm("nombre") + ToTerm("=") + cad + ToTerm("duracion") + ToTerm("=") + num + ToTerm(">");

LC.Rule= LC+Eos +ToTerm("<")+ToTerm("canal")+ ToTerm("numero")+ToTerm("=")+ num+ ToTerm(">")+Eos+Indent+ LNO+Eos+Dedent +ToTerm("<")+ToTerm("/")+ToTerm("canal")+ToTerm(">")
        | ToTerm("<") + ToTerm("canal") + ToTerm("numero") + ToTerm("=") + num + ToTerm(">") + Eos + Indent + LNO + Eos + Dedent + ToTerm("<") + ToTerm("/") + ToTerm("canal") + ToTerm(">");
		
LNO.Rule= LNO +Eos+ ToTerm("<") + ToTerm("nota") + ToTerm("duracion") + ToTerm("=") + num + ToTerm("frecuencia") + ToTerm("=") + num + ToTerm(">")
        | ToTerm("<") + ToTerm("nota") + ToTerm("duracion") + ToTerm("=") + num + ToTerm("frecuencia") + ToTerm("=") + num + ToTerm(">");

LD.Rule= LD+ToTerm("<")+ToTerm("datos")+ToTerm(">")+Eos+Indent+ LSD+Eos+Dedent +ToTerm("<")+ToTerm("/")+ToTerm("datos")+ToTerm(">")
        | ToTerm("<") + ToTerm("datos") + ToTerm(">") + Eos + Indent + LSD + Eos + Dedent + ToTerm("<") + ToTerm("/") + ToTerm("datos") + ToTerm(">");

LSD.Rule= LSD+Eos+ S
        |LSD+S
		|S;

S.Rule= ToTerm("<")+ToTerm("canal")+ToTerm(">")+ Idn+ ToTerm("<")+ToTerm("/")+ToTerm("canal")+ToTerm(">")
	|ToTerm("<")+ToTerm("nota")+ToTerm(">")+ NM+ ToTerm("<")+ToTerm("/")+ToTerm("nota")+ToTerm(">")
	|ToTerm("<")+ToTerm("octava")+ToTerm(">")+ num+ ToTerm("<")+ToTerm("/")+ToTerm("octava")+ToTerm(">")
	|ToTerm("<")+ToTerm("duracion")+ToTerm(">")+ num +ToTerm("<")+ToTerm("/")+ToTerm("duracion")+ToTerm(">");

NM.Rule = ToTerm("Do")
        | "Do#"
        | "Re"
        | "Re#"
        | "Mi"
        | "Fa"
        | "Fa#"
        | "Sol"
        | "Sol#"
        | "La"
        | "La#"
        | "Si";

Idn.Rule = id
        | num;

this.Root = LAM;
        }
        public override void CreateTokenFilters(LanguageData language, TokenFilterList filters)
        {
            var outlineFilter = new CodeOutlineFilter(language.GrammarData,
              OutlineOptions.ProduceIndents | OutlineOptions.CheckBraces, ToTerm(@"\")); // "\" is continuation symbol
            filters.Add(outlineFilter);
        }
    }
}
